package com.github.h4de5ing.kmp.rtk

import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.net.Socket
import java.net.SocketTimeoutException
import java.util.*

class SocketClient {
    private var socket: Socket? = null
    private var `is`: InputStream? = null
    private var os: OutputStream? = null
    private var isRunning = false

    fun start(
        host: String?,
        port: Int,
        mountPoint: String?,
        username: String?,
        password: String?,
        change: (ByteArray, Int) -> Unit
    ) {
        Thread {
            println("Thread------------------------network")
            try {
                isRunning = true
                socket = Socket(host, port)
                socket!!.soTimeout = 10000
                os = socket!!.getOutputStream()
                `is` = socket!!.getInputStream()
                val header = formatHeader(mountPoint, username, password)
                os?.write(header.toByteArray())
                os?.flush()
                val data = ByteArray(1024)
                var length: Int
                length = `is`?.read(data) ?: 0
                if (length > 0) {
                    val result = String(data, 0, length)
                    println("result = $result")
                    if (result.contains("OK")) {
                        while (isRunning) {
                            try {
                                if (`is` != null) length = `is`!!.read(data)
                            } catch (e: Exception) {
                                if (e is SocketTimeoutException) {
                                    continue
                                } else {
                                    throw e
                                }
                            }
                            if (length > 0) {
                                println("服务器返回数据:" + String(data))
                                change(data, length)
                            } else if (-1 == length) {
                                break
                            }
                        }
                    }
                }
            } catch (e: Exception) {
                isRunning = false
                e.printStackTrace()
            } finally {
                closeIO(`is`, os)
                if (socket != null) {
                    try {
                        socket!!.shutdownInput()
                        socket!!.shutdownOutput()
                        socket!!.close()
                    } catch (ignored: IOException) {
                    }
                    socket = null
                }
            }
        }.start()
    }

    fun write(data: ByteArray) {
        if (os != null) {
            try {
                os?.write(data, 0, data.size)
            } catch (e: Exception) {
                //e.printStackTrace()
            }
        }
    }

    private fun formatHeader(mountPoint: String?, username: String?, password: String?): String {
        val sb = StringBuilder()
        if (mountPoint == null) {
            sb.append("GET " + "/" + " HTTP/1.1\r\n")
        } else {
            sb.append("GET " + "/").append(mountPoint).append(" HTTP/1.1\r\n")
        }

        sb.append("User-Agent:NTRIP UniNtrip/0.1\r\n")
        sb.append("Accept:*/*\r\n")
        if (username != null && password != null) {
            val base = Base64.getEncoder().encodeToString("$username:$password".toByteArray())
            sb.append("Authorization: Basic ").append(base).append("\r\n")
        }
        sb.append("Connection: Keep-Alive\r\n")
        sb.append("\r\n")
        return sb.toString()
    }
}
